package com.ruoyi.open.api;

import cn.hutool.db.Page;
import cn.hutool.db.PageResult;
import cn.hutool.db.sql.Order;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.dev.domain.DevApi;
import com.ruoyi.dev.domain.DevModel;
import com.ruoyi.dev.service.IDevApiService;
import com.ruoyi.dev.service.IDevModelDataService;
import com.ruoyi.dev.service.IDevModelService;
import com.ruoyi.dev.vo.DbWhere;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * 标准的针对数据模型的CURD操作
 */
@RestController
@RequestMapping("/open/curd")
public class CurdController extends OpenController {

    @Autowired
    private IDevApiService devApiService;
    @Autowired
    private IDevModelDataService devModelDataService;
    @Autowired
    private IDevModelService devModelService;

    /**
     * 分页查询
     * @param uri
     * @param request
     * @return
     */
    @GetMapping("{uri}")
    public AjaxResult list(@PathVariable("uri") String uri, HttpServletRequest request){
        DevApi devApi = devApiService.selectDevApiByUri(uri);
        if(devApi == null){
            return AjaxResult.error(404, "未知请求");
        }
        if(checkToken(request)){
            return AjaxResult.error("签名验证失败");
        }

        Integer page = getIntParam(request, "pageNum", 1) - 1;
        Integer limit = getIntParam(request, "pageSize", 10);
        String orderBy = request.getParameter("orderBy");
        Page p = new Page(page, limit);
        if(StringUtils.isNotEmpty(orderBy)){
            p.addOrder(new Order(orderBy));
        }

        DbWhere dbWhere = null;
        String sf = request.getParameter("field");
        String exp = request.getParameter("exp");
        if(StringUtils.isNotEmpty(sf) && StringUtils.isNotEmpty(exp)){
            dbWhere = new DbWhere();
            dbWhere.setField(sf);
            dbWhere.setExp(exp);
            dbWhere.setVal(request.getParameter("val"));
        }
        DevModel devModel = devModelService.selectDevModelDetail(devApi.getModelId());
        PageResult list = devModelDataService.selectDevModelDataList(devModel.getCode(), dbWhere,  p);
        AjaxResult rspData = new AjaxResult();
        rspData.put(AjaxResult.CODE_TAG, HttpStatus.SUCCESS);
        rspData.put(AjaxResult.MSG_TAG, "查询成功");
        rspData.put("rows", list);
        rspData.put("total", list.getTotal());
        return rspData;
    }

    /**
     * 新增
     * @param uri
     * @param data
     * @param request
     * @return
     */
    @PostMapping("{uri}")
    public AjaxResult post(@PathVariable("uri") String uri, @RequestBody Map<String, Object> data, HttpServletRequest request){
        DevApi devApi = devApiService.selectDevApiByUri(uri);
        if(devApi == null){
            return AjaxResult.error(404, "未知请求");
        }
        if(devApi.getMode().equalsIgnoreCase(DevApi.MODE_READ)){
            return AjaxResult.error("只读接口不支持POST方法");
        }
        if(checkToken(request)){
            return AjaxResult.error("签名验证失败");
        }
        DevModel devModel = devModelService.selectDevModelDetail(devApi.getModelId());
        devModelDataService.insertDevModelData(devModel.getCode(), data);
        return AjaxResult.success("新增数据成功");
    }

    /**
     * 更新
     * @param uri
     * @param data
     * @param request
     * @return
     */
    @PutMapping("{uri}")
    public AjaxResult put(@PathVariable("uri") String uri, @RequestBody Map<String, Object> data, HttpServletRequest request){
        DevApi devApi = devApiService.selectDevApiByUri(uri);
        if(devApi == null){
            return AjaxResult.error(404, "未知请求");
        }
        if(devApi.getMode().equalsIgnoreCase(DevApi.MODE_READ)){
            return AjaxResult.error("只读接口不支持PUT方法");
        }
        if(checkToken(request)){
            return AjaxResult.error("签名验证失败");
        }
        DevModel devModel = devModelService.selectDevModelDetail(devApi.getModelId());
        if(!data.containsKey(devModel.getPkField())){
            return AjaxResult.error("更新数据时，必须有主键字段");
        }
        devModelDataService.updateDevModelData(devModel.getCode(), data);
        return AjaxResult.success("更新数据成功");
    }

    /**
     * 更新
     * @param uri
     * @param data
     * @param request
     * @return
     */
    @PatchMapping("{uri}")
    public AjaxResult patch(@PathVariable("uri") String uri, @RequestBody Map<String, Object> data, HttpServletRequest request){
        DevApi devApi = devApiService.selectDevApiByUri(uri);
        if(devApi == null){
            return AjaxResult.error(404, "未知请求");
        }
        if(devApi.getMode().equalsIgnoreCase(DevApi.MODE_READ)){
            return AjaxResult.error("只读接口不支持PATCH方法");
        }
        if(checkToken(request)){
            return AjaxResult.error("签名验证失败");
        }
        DevModel devModel = devModelService.selectDevModelDetail(devApi.getModelId());
        if(!data.containsKey(devModel.getPkField())){
            devModelDataService.insertDevModelData(devModel.getCode(), data);
        }else{
            devModelDataService.updateDevModelData(devModel.getCode(), data);
        }

        return AjaxResult.success("保存数据成功");
    }

    /**
     * 删除
     * @param uri
     * @param ids
     * @param request
     * @return
     */
    @DeleteMapping("{uri}")
    public AjaxResult delete(@PathVariable("uri") String uri, @RequestParam("id") Long[] ids, HttpServletRequest request){
        DevApi devApi = devApiService.selectDevApiByUri(uri);
        if(devApi == null){
            return AjaxResult.error(404, "未知请求");
        }
        if(devApi.getMode().equalsIgnoreCase(DevApi.MODE_SYNC)){
            return AjaxResult.error("只有同步数据接口才允许删除");
        }
        if(checkToken(request)){
            return AjaxResult.error("签名验证失败");
        }
        if(StringUtils.isEmpty(ids)){
            return AjaxResult.error("删除数据时必须有主键数据");
        }else{
            DevModel devModel = devModelService.selectDevModelDetail(devApi.getModelId());
            devModelDataService.deleteDevModelDataByIds(devModel.getCode(), ids);
        }
        return AjaxResult.success("删除数据成功");
    }
}
